package com.boarsoft.boar.sys.biz;

import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.boar.sys.SysUserBiz;
import com.boarsoft.boar.sys.entity.SysToken;
import com.boarsoft.boar.sys.entity.SysUser;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.common.util.DateUtil;
import com.boarsoft.hibernate.biz.SimpleBizImpl;

@Component("sysUserBiz")
public class SysUserBizImpl extends SimpleBizImpl implements SysUserBiz {

	@Override
	@Transactional(readOnly = true)
	public PagedResult<SysUser> list(String corpId, String deptId, String key, int pageNo, int pageSize, String orderBy) {
		StringBuffer sb = new StringBuffer();
		if (Util.strIsNotEmpty(corpId)) {
			sb.append(" and corpId='").append(corpId).append("'");
		}
		if (Util.strIsNotEmpty(deptId)) {
			sb.append(" and deptId = '").append(deptId).append("'");
		}
		if (Util.strIsNotEmpty(key)) {
			sb.append("and (phone like '%").append(key);
			sb.append("%' or email like '%").append(key);
			sb.append("%' or code like '%").append(key);
			sb.append("%' or name like '%").append(key);
			sb.append("%')");
		}
		int total = dao.getTotal(SysUser.class, sb.toString());
		if (Util.strIsNotEmpty(orderBy)) {
			String ob = Util.array2str(orderBy.split(","), ",");
			sb.append(" order by ").append(ob).append(" desc");
		} else {
			sb.append(" order by name");
		}
		List<SysUser> alt = dao.list(SysUser.class, sb.toString(), pageNo, pageSize);
		return new PagedResult<SysUser>(total, alt, pageNo, pageSize);
	}

	@Override
	@Transactional
	public boolean add(SysUser o) {
		if (this.find(o.getCode()) == null) {
			dao.save(o);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public void update(SysUser user) {
		dao.merge(user);
	}

	@Override
	@Transactional
	public Boolean delete(String id) {
		dao.delete(SysUser.class, id);
		//TODO 删除其它关联的数据
		return true;
	}

	@Override
	@Transactional(readOnly = true)
	public SysUser find(String code) {
		StringBuilder sb = new StringBuilder();
		sb.append(" and code='").append(code).append("'");
		return (SysUser) dao.find(SysUser.class, sb.toString());
	}

	@Override
	@Transactional(readOnly = true)
	public ReplyInfo<Object> login(String code, String password) {
		SysUser o = (SysUser) this.find(code);
		if (o == null) {
			return Constants.REPLY_INFO_NOTFOUND;
		}
		if (o.getStatus() != SysUser.STATUS_INUSE) {
			return Constants.REPLY_INFO_NOUSE;
		}
		if (!o.getPassword().equals(password)) {
			return new ReplyInfo<Object>("login.failed");
		}
		dao.evict(o);
		return new ReplyInfo<Object>(true, o);
	}

	/**
	 * 根据UID查询用户的TOKEN
	 * 
	 * @param uid
	 * @return
	 */
	@Transactional(readOnly = true)
	public SysToken getToken(String uid) {
		return (SysToken) dao.find(SysToken.class, String.format("and userId='%s'", uid));
	}

	@Override
	@Transactional(readOnly = true)
	public boolean checkToken(String token) {
		SysToken o = (SysToken) dao.get(SysToken.class, token);
		if (o != null) {
			o.setTime(Util.getStdfDateTime());// 更新时间
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public void logout(String uid) {
		dao.delete(SysToken.class, uid);
	}

	@Override
	@Transactional
	public ReplyInfo<String> register(SysUser o) {
		// 因为注册时手机和邮箱可以任选一项
		StringBuilder sb = new StringBuilder();
		sb.append("and (1=0");
		if (Util.strIsNotEmpty(o.getEmail())) {
			sb.append(" or email='").append(o.getEmail()).append("'");
		}
		if (Util.strIsNotEmpty(o.getPhone())) {
			sb.append(" or phone='").append(o.getPhone()).append("'");
		}
		sb.append(")");
		// 如果任意一项查得出结果，注册都失败
		SysUser a = (SysUser) dao.find(SysUser.class, sb.toString());
		if (a != null) {
			return new ReplyInfo<String>("reg.duplicated");
		}
		dao.merge(o);
		return new ReplyInfo<String>(true, o.getId());
	}

	@Override
	@Transactional(readOnly = true)
	public SysUser get(String id) {
		return (SysUser) dao.get(SysUser.class, id);
	}

	@Override
	@Transactional
	public void saveToken(SysUser uo, int validity) {
		// 与WEB端（由validity指定）相比，APP端的TOKEN有效期更长（7天）
		if (validity < 1) {
			validity = 10080;// 7天
		}
		String ed = Util.date2str(DateUtil.addMinute(new Date(), validity), Util.STDDTF);
		// TOKEN表由定时任务自动清除，所以这里查得到的TOKEN都是有效的
		SysToken o = this.getToken(uo.getId());
		if (o == null) {
			// SysToken与BaseToken不同，它的ID是Hibernate自动生成的
			o = new SysToken();
			o.setUserId(uo.getId());
			o.setTime(ed);// 更新时间
			dao.save(o);
		} else {
			o.setTime(ed);// 更新时间
		}
		// 更新用户的TOKEN
		log.info("update token {} of user {}", o.getToken(), uo.getId());
		uo.setToken(o.getToken());
		dao.merge(uo);
	}

}